package com.geovis.emergency.spd.controller.pc;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.common.core.api.Result;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDisasterEventService;
import com.geovis.emergency.spd.cache.DictCache;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDisasterEvent;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcDisasterConstant;
import com.geovis.emergency.spd.entity.pc.pojo.enums.DisasterEventStatusEnum;
import com.geovis.emergency.spd.entity.system.entity.SystemDictData;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * <p>
 *  应急预案指挥模块-演练事件统计接口
 * </p>
 *
 * @author Lonsho
 * @version 1.0
 * @date 2022/7/6
 */
@RestController
@RequestMapping("/pc/drill/event/statistics")
@RequiredArgsConstructor
@Api(value = "应急预案指挥模块-演练事件统计", tags = "应急预案指挥模块-演练事件统计接口")
@Slf4j
@Validated
public class PcDrillEventStatisticsController {

    private final IPcDrillDisasterEventService pcDrillDisasterEventService;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "按事件类型统计", notes = "按事件类型统计接口")
    @PostMapping("/eventType/{drillId}")
    public Result<List<Map<String, Object>>> eventType(@PathVariable("drillId") String drillId) {

        List<Map<String, Object>> listMaps = pcDrillDisasterEventService.listMaps(
                Wrappers.<PcDrillDisasterEvent>query()
                        .select("type", "count(1) as count")
                        .lambda()
                        .eq(PcDrillDisasterEvent::getPcDrillId, drillId)
                        .and(s -> s.eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.IN_PROGRESS.getCode())
                                .or().eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.COMPLETED.getCode())
                        )
                        .groupBy(PcDrillDisasterEvent::getType)
        );
        List<Map<String, Object>> resultList = Lists.newArrayList();
        for (Map<String, Object> map : listMaps) {
            String type = map.get("type").toString();
            Integer count = Integer.parseInt(map.get("count").toString());
            Map<String, Object> resultMap = Maps.newHashMap();
            resultMap.put("value",count);
            resultMap.put("name", DictCache.getDictValue(PcDisasterConstant.DISASTER_TYPE,type));
            resultList.add(resultMap);
        }
        return Result.ok(resultList);
    }
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "按行政区划统计", notes = "按行政区划统计接口")
    @PostMapping("/regionType/{drillId}")
    public Result<Map<String, Object>> regionType(@PathVariable("drillId") String drillId) {

        List<Map<String, Object>> listMaps = pcDrillDisasterEventService.listMaps(
                Wrappers.<PcDrillDisasterEvent>query()
                        .select("type", "count(1) as count")
                        .lambda()
                        .eq(PcDrillDisasterEvent::getPcDrillId, drillId)
                        .and(s -> s.eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.IN_PROGRESS.getCode())
                                .or().eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.COMPLETED.getCode())
                        )
                        .groupBy(PcDrillDisasterEvent::getType)
        );
        List<Map<String, Object>> resultList = Lists.newArrayList();
        for (Map<String, Object> map : listMaps) {
            String type = map.get("type").toString();
            Integer count = Integer.parseInt(map.get("count").toString());
            Map<String, Object> resultMap = Maps.newHashMap();
            resultMap.put("data",Lists.newArrayList(count));
            resultMap.put("type","bar");
//            resultMap.put("stack","总计"); //纵向分布
            resultMap.put("name", DictCache.getDictValue(PcDisasterConstant.DISASTER_TYPE,type));
            resultList.add(resultMap);
        }
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("series",resultList);
        resultMap.put("nameList",Lists.newArrayList("城阳区"));
        return Result.ok(resultMap);
    }
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "按事件等级统计", notes = "按事件等级接口")
    @PostMapping("/eventLevel/{drillId}")
    public Result<Map<String, Object>> eventLevel(@PathVariable("drillId") String drillId) {

        List<Map<String, Object>> listMaps = pcDrillDisasterEventService.listMaps(
                Wrappers.<PcDrillDisasterEvent>query()
                        .select("COALESCE(level,'其他') as level", "count(1) as count")
                        .lambda()
                        .eq(PcDrillDisasterEvent::getPcDrillId, drillId)
                        .and(s -> s.eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.IN_PROGRESS.getCode())
                                .or().eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.COMPLETED.getCode())
                        )
                        .groupBy(PcDrillDisasterEvent::getLevel)
        );
        List<SystemDictData> dictDataList = DictCache.getDictData(PcDisasterConstant.EVENT_LEVEL);
        List<Integer> dataList = Lists.newArrayList();
        List<String> nameList = Lists.newArrayList();
        for (SystemDictData dictData : dictDataList) {
            Optional<Map<String, Object>> first = listMaps.stream().filter(s -> dictData.getDataKey().equals(s.get("level").toString())).findFirst();
            if (first.isPresent()){
                Integer count = Integer.parseInt(first.get().get("count").toString());
                dataList.add(count);
            }else {
                dataList.add(0);
            }
            nameList.add(dictData.getDataValue());
        }
        Optional<Map<String, Object>> first = listMaps.stream().filter(s -> "其他".equals(s.get("level").toString())).findFirst();
        if (first.isPresent()){
            dataList.add(Integer.parseInt(first.get().get("count").toString()));
            nameList.add(first.get().get("level").toString());
        }
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("nameList",nameList);
        resultMap.put("dataList",dataList);
        return Result.ok(resultMap);
    }
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "按上报统计时间", notes = "按上报时间统计接口")
    @PostMapping("/reportTime/{drillId}")
    public Result<Map<String, Object>> reportTime(@PathVariable("drillId") String drillId) {

        List<Map<String, Object>> listMaps = pcDrillDisasterEventService.listMaps(
                Wrappers.<PcDrillDisasterEvent>query()
                        .select("to_char(submit_time, 'hh24:00') as time", "count(1) as count")
                        .groupBy("to_char(submit_time, 'hh24:00')")
                        .lambda()
                        .and(s -> s.eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.IN_PROGRESS.getCode())
                                .or().eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.COMPLETED.getCode())
                        )
                        .eq(PcDrillDisasterEvent::getPcDrillId, drillId)
        );
        List<Integer> dataList = Lists.newArrayList();
        List<String> nameList = Lists.newArrayList();
        for (int i = 0; i < 24; i++) {
            String currentTime = StrUtil.format("{}:00",i);
            if (i<10) {
                currentTime = StrUtil.format("0{}:00",i);
            }
            nameList.add(currentTime);

            String finalCurrentTime = currentTime;
            Optional<Map<String, Object>> first = listMaps.stream().filter(s -> s.get("time").toString().equals(finalCurrentTime)).findFirst();
            if (first.isPresent()){
                Integer count = Integer.parseInt(first.get().get("count").toString());
                dataList.add(count);
            }else {
                dataList.add(0);
            }
        }
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("nameList",nameList);
        resultMap.put("dataList",dataList);
        return Result.ok(resultMap);
    }
}
